import json
import os
import time

from .leetcode_operation import LeetCodeOperation


class DiscussTopic(LeetCodeOperation):
    def __init__(self, requests_manager, base_url="https://leetcode.cn", **params):
        super().__init__(requests_manager, base_url)
        self.params = params.get('params')
        self.filename = "discuss_topic.json"
        self.endpoint = 'graphql'

    def generate_payload(self):
        query_string = "\n    query discussTopic($slug: String) {\n  solutionArticle(slug: $slug, orderBy: DEFAULT) {\n    ...solutionArticle\n    content\n    next {\n      slug\n      title\n    }\n    prev {\n      slug\n      title\n    }\n  }\n}\n    \n    fragment solutionArticle on SolutionArticleNode {\n  ipRegion\n  rewardEnabled\n  canEditReward\n  uuid\n  title\n  slug\n  sunk\n  chargeType\n  status\n  identifier\n  canEdit\n  canSee\n  reactionType\n  reactionsV2 {\n    count\n    reactionType\n  }\n  tags {\n    name\n    nameTranslated\n    slug\n    tagType\n  }\n  createdAt\n  thumbnail\n  author {\n    username\n    isDiscussAdmin\n    isDiscussStaff\n    profile {\n      userAvatar\n      userSlug\n      realName\n      reputation\n    }\n  }\n  summary\n  topic {\n    id\n    subscribed\n    commentCount\n    viewCount\n    post {\n      id\n      status\n      voteStatus\n      isOwnPost\n    }\n  }\n  byLeetcode\n  isMyFavorite\n  isMostPopular\n  favoriteCount\n  isEditorsPick\n  hitCount\n  videosInfo {\n    videoId\n    coverUrl\n    duration\n  }\n}\n    "
        return {
            "query": query_string,
            "variables": self.params,
            "operationName": "discussTopic"
        }

    def parse_graphql_data(self, data):
        solution_article_data = data.get('data', {}).get('solutionArticle', {})
        if not solution_article_data:
            return {}
        parsed_data = {
            'ipRegion': solution_article_data.get('ipRegion'),
            'rewardEnabled': solution_article_data.get('rewardEnabled'),
            'canEditReward': solution_article_data.get('canEditReward'),
            'uuid': solution_article_data.get('uuid'),
            'title': solution_article_data.get('title'),
            'content': solution_article_data.get('content'),
            'slug': solution_article_data.get('slug'),
            'sunk': solution_article_data.get('sunk'),
            'chargeType': solution_article_data.get('chargeType'),
            'status': solution_article_data.get('status'),
            'identifier': solution_article_data.get('identifier'),
            'canEdit': solution_article_data.get('canEdit'),
            'canSee': solution_article_data.get('canSee'),
            'reactionType': solution_article_data.get('reactionType'),
            'reactionsV2': [
                {'count': reaction.get('count'), 'reactionType': reaction.get('reactionType')} 
                for reaction in solution_article_data.get('reactionsV2', [])
            ],
            'tags': [
                {'name': tag.get('name'), 'nameTranslated': tag.get('nameTranslated'), 'slug': tag.get('slug'), 'tagType': tag.get('tagType')} 
                for tag in solution_article_data.get('tags', [])
            ],
            'createdAt': solution_article_data.get('createdAt'),
            'thumbnail': solution_article_data.get('thumbnail'),
            'author': {
                'username': solution_article_data.get('author', {}).get('username'),
                'isDiscussAdmin': solution_article_data.get('author', {}).get('isDiscussAdmin'),
                'isDiscussStaff': solution_article_data.get('author', {}).get('isDiscussStaff'),
                'profile': {
                    'userAvatar': solution_article_data.get('author', {}).get('profile', {}).get('userAvatar'),
                    'userSlug': solution_article_data.get('author', {}).get('profile', {}).get('userSlug'),
                    'realName': solution_article_data.get('author', {}).get('profile', {}).get('realName'),
                    'reputation': solution_article_data.get('author', {}).get('profile', {}).get('reputation'),
                }
            },
            'summary': solution_article_data.get('summary'),
            # 'topic': {
            #     # Extract fields from the 'topic' object
            # },
            # Additional fields as per the GraphQL query
        }

        return parsed_data


    def fetch_all_data(self, request_interval=1):
        question_topics_folder = "QuestionTopicsList"
        question_topics_path = os.path.join(self.directory, question_topics_folder)
        
        output_folder = "DiscussTopic"

        os.makedirs(os.path.join(self.directory, output_folder), exist_ok=True)

        for filename in os.listdir(question_topics_path):
            if filename.endswith(".json"):
                question_slug = filename[:-5]
                file_path = os.path.join(question_topics_folder, filename)
                
                if os.path.exists(os.path.join(self.directory, 'Submission', filename)) or os.path.exists(os.path.join(self.directory, output_folder, filename)): # output_folder
                    continue
                
                self.logger.info(f"filename: {filename}")
                
                data = self.load_json(file_path)
                topic_slugs = [topic['slug'] for topic in data.get('topics', [])]

                all_topics_data = []

                for topic_slug in topic_slugs:
                    self.logger.info(f"topic_slug: {topic_slug}")
                    self.params.update({'slug': topic_slug})
                    topic_data = self.fetch_data(self.endpoint, method='POST')
                    parsed_data = self.parse_graphql_data(topic_data)
                    if parsed_data:
                        all_topics_data.append(parsed_data)
                    time.sleep(request_interval)

                output_file_path = os.path.join(output_folder, f"{question_slug}.json")
                if all_topics_data:
                    self.save_json(all_topics_data, output_file_path)

    def execute(self):
        data = self.fetch_data(self.endpoint, method='POST')
        parsed_data = self.parse_graphql_data(data)
        self.save_json(parsed_data, self.filename)
